package jia.editor.widgets;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.awt.image.WritableRaster;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Vector;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import jia.game.GenericFlags;

/**
 *
 * @author gryffonx
 */
public class SpriteIconTable extends JTable{
    
    public static final int CREATURES = 1;
    public static final int CHARACTERS = 2;
    public static final int SPELLS = 3;
    public static final int MISSILE = 4;
    
    private IconTableHandler tableHandler;
    private JTableImageIconRenderer cellRenderer;
    private TableColumn imageColumn;
    private static JFrame testFrame;
    protected int[] PIXEL_SPEC = new int[4];
    
    private int vColIndex = 0;
    
    /**
     * Creates a new instance of SpriteIconTable
     */
    public SpriteIconTable(int tableType) {
        super();
        
        ArrayList testData = null;
        
        if (tableType == SpriteIconTable.CREATURES){
            //set up a simple array of objects to be used as a test.  this will be deleted later
            testData = creatureTestData();            
        }else if (tableType == SpriteIconTable.CHARACTERS) {
            testData = characterTestData();  
        }
        
        String[] colNames = {"Icon", "Name", "Filename"};
        
        tableHandler = new IconTableHandler();
        cellRenderer = new JTableImageIconRenderer();
        
        this.setModel(tableHandler);
        this.setGridColor(Color.gray);
        
        //populate the table with data
        populateTable(testData);
        
        //now, set the first column to show the image icons rather than the string value
        imageColumn = this.getColumnModel().getColumn(0);
        imageColumn.setCellRenderer(cellRenderer);
                
        packRows(this, 1);
        
        this.setColumnWidth(1, 96);
        this.setColumnWidth(1, 350);
        this.setColumnWidth(1, 350);
    }
    
    /**This method should be called to set the column
     *at pColumn index to a width of pWidth.
     */
    public void setColumnWidth(int pColumn, int pWidth){
        //Get the column model.
        TableColumnModel colModel = getColumnModel();
        //Get the column at index pColumn, and set its preferred width.
        colModel.getColumn(pColumn).setPreferredWidth(pWidth);
    }
    
    private ArrayList creatureTestData(){
        ArrayList testarrayLst = new ArrayList();
        testarrayLst.add(new SpriteObject("aurak.gif", "Aurak Draconian", "creature"));
        testarrayLst.add(new SpriteObject("cm_Goblin02.png", "Goblin", "creature"));
        testarrayLst.add(new SpriteObject("cm_WaterElemental.png", "Water Elemental", "creature"));
        testarrayLst.add(new SpriteObject("cn_IconElfFemaleMagicUser2.png", "Elf Magic User", "creature"));
        testarrayLst.add(new SpriteObject("cm_DuergarHammer.png", "Duergar Dwarf", "creature"));
        testarrayLst.add(new SpriteObject("cm_Efreet.png", "Efreet", "creature"));
        
        return testarrayLst;
    }

    private ArrayList characterTestData(){
        ArrayList testarrayLst = new ArrayList();
        
        testarrayLst.add(new SpriteObject("C_Icon_001.png", "Fighter", "creature"));
        testarrayLst.add(new SpriteObject("C_Icon_002.png", "Fighter", "creature"));
        testarrayLst.add(new SpriteObject("C_Icon_003.png", "Fighter", "creature"));
        testarrayLst.add(new SpriteObject("C_Icon_004.png", "Fighter", "creature"));
        testarrayLst.add(new SpriteObject("C_Icon_005.png", "Fighter", "creature"));
        testarrayLst.add(new SpriteObject("C_Icon_006.png", "Fighter", "creature"));
        
        
        return testarrayLst;
    }
    
    protected BufferedImage setTransparency(BufferedImage initImg, int[] transColor) {
        int width = initImg.getWidth();
        int height = initImg.getHeight();
        
        if (!initImg.getColorModel().hasAlpha()) {
            BufferedImage newImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
            Graphics g = newImg.getGraphics();
            g.drawImage(initImg, 0, 0, width, height, null);
            initImg = newImg;
        }
        
        WritableRaster myRaster = initImg.getRaster();
        int[] transPixel = new int[]{0, 0, 0, 0};
        
        for (int px = 0; px < width; px++) {
            for (int py = 0; py < height; py++) {
                int[] pixel = myRaster.getPixel(px, py, PIXEL_SPEC);
                if ((pixel[0] == transColor[0]) &&
                    (pixel[1] == transColor[1]) &&
                    (pixel[2] == transColor[2])) {
                    
                    myRaster.setPixel(px, py, transPixel);
                }
            }
        }
        
        return initImg;
    }
    
    public void populateTable(ArrayList dataList){
        ImageIcon testIcon;
        for (int i=0; i<dataList.size(); i++){
            SpriteObject thisObj = (SpriteObject)dataList.get(i);
            
            //URL imgUrl = getClass().getClassLoader().getResource("resources/images/sprites/" + thisObj.getFileName());
            // System.out.println(imgUrl.toString());
            BufferedImage img = null;
            try {
                img = ImageIO.read(new File("resources/images/sprites/" + thisObj.getFileName()));
            } catch (Exception e) {
                if (GenericFlags.errorMessages){
                    e.printStackTrace();
                }
                
            }
            
            int[] transColor = img.getRaster().getPixel(0, 0, new int[3]);
            img = setTransparency(img, transColor);
            
            testIcon = new ImageIcon(img);
            tableHandler.addRowToTable(testIcon, thisObj.getIconName(), thisObj.getCategory());
            
            setRowHeight(i, testIcon.getImage().getHeight(null));
        }
    }
    
    // Returns the preferred height of a row.
    // The result is equal to the tallest cell in the row.
    public int getPreferredRowHeight(JTable table, int rowIndex, int margin) {
        // Get the current default height for all rows
        int height = table.getRowHeight();
        
        // Determine highest cell in the row
        for (int c=0; c<table.getColumnCount(); c++) {
            TableCellRenderer renderer = table.getCellRenderer(rowIndex, c);
            Component comp = table.prepareRenderer(renderer, rowIndex, c);
            int h = comp.getPreferredSize().height + 2*margin;
            height = Math.max(height, h);
        }
        return height;
    }
    
    // The height of each row is set to the preferred height of the
    // tallest cell in that row.
    public void packRows(JTable table, int margin) {
        packRows(table, 0, table.getRowCount(), margin);
    }
    
    // For each row >= start and < end, the height of a
    // row is set to the preferred height of the tallest cell
    // in that row.
    public void packRows(JTable table, int start, int end, int margin) {
        for (int r=0; r<table.getRowCount(); r++) {
            // Get the preferred height
            int h = getPreferredRowHeight(table, r, margin);
            
            // Now set the row height using the preferred height
            if (table.getRowHeight(r) != h) {
                table.setRowHeight(r, h);
            }
        }
    }
    
    class SpriteObject{
        private String fileName;
        private String iconName;
        private String category;
        
        public SpriteObject(String fileName, String iconName, String category){
            setFileName(fileName);
            setIconName(iconName);
            setCategory(category);
        }
        
        public String getFileName() {
            return fileName;
        }
        
        public void setFileName(String fileName) {
            this.fileName = fileName;
        }
        
        public String getIconName() {
            return iconName;
        }
        
        public void setIconName(String iconName) {
            this.iconName = iconName;
        }
        
        public String getCategory() {
            return category;
        }
        
        public void setCategory(String category) {
            this.category = category;
        }
    }
    
    class IconTableHandler extends AbstractTableModel {
        
        private Vector<Object[]> dataRows;
        
        /** Creates a new instance of IconTableHandler */
        public IconTableHandler() {
            dataRows = new Vector<Object[]>(); // setup the vector ]
        }
        /**
         * Adds a row to the table.  The player character list only
         * contains 3 columns, so this method only takes 3 string arguments
         *
         * @param a - Column 1 value
         * @param b - Column 2 value
         * @param c - Column 3 value
         */
        public void addRowToTable(ImageIcon img, String b, String c) {
            Object[] rowData = new Object[3];
            
            rowData[0] = img;
            rowData[1] = b;
            rowData[2] = c;

            
            // Add the data to a vector
            dataRows.addElement(rowData);
            
            // Tell the table there is new data
            fireTableChanged(null);
        }
        
        public void updateTableRow(int rowIndex, String a, String b, String c){
            Object[] rowData = new String[3];
            rowData[0] = a;
            rowData[1] = b;
            rowData[2] = c;

            
            dataRows.setElementAt(rowData, rowIndex);
            
            fireTableChanged(null);
            
        }
        
        public void updateTableRow(int rowIndex, String name, String hp){
            Object[] rowData = new Object[3];
            rowData[0] = name;
            rowData[1] = "Fighter";
            rowData[2] = hp;

            
            dataRows.setElementAt(rowData, rowIndex);
            
            fireTableChanged(null);
            
        }
        
        /**
         * Returns the number of columns for this table as an int.  Hard coded to
         * 3 for the purposes of being used in the PlayerCharacterList component
         *
         * @return
         */
        public int getColumnCount() {
            return 3;
        }
        
        /**
         * Returns the number of rows that currently have data for this table as an int.
         *
         * @return
         */
        public int getRowCount() {
            if (dataRows != null) {
                return dataRows.size();
            } else {
                return -1;
            }
        }
        
        /**
         * Targets a specific cell in the table and returns its value as an Object
         *
         * @param row
         * @param column
         * @return
         */
        public Object getValueAt(int row, int column) {
            if (dataRows != null) {
                return ((dataRows.elementAt(row)))[column];
            } else {
                return null;
            }
        }
        
    }
    
    class JTableImageIconRenderer extends DefaultTableCellRenderer {
        public void setValue(Object value) {
            if (value instanceof ImageIcon) {
                ImageIcon c = (ImageIcon) value;
                setIcon(c);
            } else {
                super.setValue(value);
            }
        }
    }
    

}